package falcon.server;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.concurrent.ConcurrentLinkedQueue;

import falcon.common.Errno;
import falcon.common.FalconConfig;
import falcon.common.Log;
import falcon.protocol.Packet;
import falcon.server.processor.FalconProcessor;

public final class FalconProManager {

	public static final class Req {
		public int id;
		public Packet packet;
		public FalconByteBufHandler handler;
		public int errno;
		public String desc;
	}

	public FalconProManager(FalconConfig config) {
		m_config = config;
		m_queue = new ConcurrentLinkedQueue<FalconProManager.Req>();
		m_sessions = new LinkedList<FalconSession>();
		m_processors = new FalconProcessor[4];
		for (int i = 0; i < m_processors.length; i ++) {
			FalconProcessor processor = new FalconProcessor();
			processor.bind(this);
			m_processors[i] = processor;
			new Thread(processor).start();
		}
	}
	
	public void addReq(Packet packet, FalconByteBufHandler handler) {
		FalconProManager.Req req = new Req();
		req.id = packet.id;
		req.packet = packet;
		req.handler = handler;
		req.errno = Errno.SUCCESS;
		req.desc = "成功";
		m_queue.add(req);
	}
	
	public FalconProManager.Req getReq() {
		return m_queue.poll();
	}
	
	public FalconConfig getConfig() {
		return m_config;
	}
	
	public synchronized FalconSession[] getSessionList() {
		FalconSession[] array = m_sessions.toArray(new FalconSession[0]);
		return array;
	}
	
	public synchronized FalconSession getSession(String clientHost, String loginUser) {
		Iterator<FalconSession> iterator = m_sessions.iterator();
		while (iterator.hasNext()) {
			FalconSession session = iterator.next();
			if (!session.clientHost.equals(clientHost) || !session.loginUser.equals(loginUser)) {
				continue;
			}
			return session;
		}
		return null;
	}
	
	public synchronized void updateSession(String clientHost, int clientPort, String loginUser, FalconByteBufHandler handler) {
		FalconSession session = getSession(clientHost, loginUser);
		if (session == null) {
			session = new FalconSession();
			m_sessions.addLast(session);
		} else if (session.handler != handler) {
			session.handler.setSession(null);
			session.handler.channelClose();
		}
		session.clientHost = clientHost;
		session.clientPort = clientPort;
		session.loginUser = loginUser;
		session.handler = handler;
		session.handler.setSession(session);
		session.loginTime = System.currentTimeMillis();
	}
	
	public synchronized void removeSession(FalconSession session) {
		if (session == null) {
			return;
		}
		Iterator<FalconSession> iterator = m_sessions.iterator();
		while (iterator.hasNext()) {
			FalconSession s = iterator.next();
			if (s != session) {
				continue;
			}
			Log.log("remove session;clientHost=%s;loginUser=%s", session.clientHost, session.loginUser);
			iterator.remove();
			session.handler.setSession(null);
			session.handler.channelClose();
			return;
		}
	}
	
	private FalconConfig m_config;
	private ConcurrentLinkedQueue<FalconProManager.Req> m_queue;
	private LinkedList<FalconSession> m_sessions;
	private FalconProcessor[] m_processors;
}
